#include "BrbflutProcess.h"
#include "Utils/LogUtil.h"
#include "Render/RenderState.h"
#include "Core/CoreGlobals.h"
#include "Game/Scene/Entity.h"
#include "Game/Component/Model.h"
#include "Render/Buffer/VertexBuffer.h"
#include "Render/Buffer/IndexBuffer.h"
#include "Render/Buffer/CustomBuffer.h"
#include "LocalShader.h"
#include "Utils/FileUtil.h"
#include "Game/GameState.h"
#include "Render/VulkanTool.h"


void BrbflutProcess::OnInit()
{
	mWidth = 512;
	mHeight = 512;

	ENQUEUE_RENDER_COMMAND(BuildModel)([this](VkCommandBuffer commandBuffer)
		{

			mCommandBuffer = RHICommandBuffer::Builder()
				.SetQueue(VK_QUEUE_GRAPHICS_BIT)
				.SetCount(1)
				.SetCommandBufferUsage(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)
				.Build();

			mDescriptor = RHIDescriptor::Builder()
				.PushShader<GenBrbflutVertexShader>()
				.PushShader<GenBrbflutFragmentShader>()
				.Build();

			mColorRenderTarget = ColorRenderTarget::Builder()
				.SetFormat(VK_FORMAT_R16G16_SFLOAT)
				.SetWidth(mWidth)
				.SetHeight(mHeight)
				.SetUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)
				.SetStoreOp(VK_ATTACHMENT_STORE_OP_STORE)
				.SetFinalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
				.SetClearColorValue({ 0.1f, 0.1f, 0.1f, 1.f })
				.Build(this, "ColorRenderTarget");

			mPipeline = GraphicsPipeline::Builder()
				.SetDescriptor(mDescriptor)
				.AddColorRenderTarget(mColorRenderTarget)
				.SetDstStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
				.SetDstAccessMask(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
				.SetSrcStageMask(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)
				.SetSrcAccessMask(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT)
				.Build();

			mRenderPass = RHIRenderPass::Builder()
				.AddRenderTarget(mColorRenderTarget)
				.AddPipeline(mPipeline)
				.SetSrcStageMask(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
				.SetSrcAccessMask(VK_ACCESS_SHADER_READ_BIT)
				.SetDstStageMask(VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
				.SetDstAccessMask(VK_ACCESS_SHADER_READ_BIT)
				.Build();

			mFrameBuffer = RHIFrameBuffer::Builder()
				.SetRenderPass(mRenderPass)
				.Build();
		});
}

void BrbflutProcess::OnTick(float deltaTime)
{
	if (GGameState->GetFrameAmount() > 0)
		return;


	ENQUEUE_RENDER_COMMAND(RecordCommand)([this](VkCommandBuffer commandBuffer)
		{
			VkCommandBuffer offlineCommandBuffer = mCommandBuffer->BeginCommandBuffer();


			VkRenderPassBeginInfo renderPassBeginInfo = mFrameBuffer->GetRenderPassBeginInfo();

			vkCmdBeginRenderPass(offlineCommandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);

			VkViewport viewport{ 0, 0, mWidth, mHeight, 0, 1 };
			vkCmdSetViewport(offlineCommandBuffer, 0, 1, &viewport);

			VkRect2D scissor{ 0, 0, mWidth, mHeight };
			vkCmdSetScissor(offlineCommandBuffer, 0, 1, &scissor);

			vkCmdBindPipeline(offlineCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, mPipeline->GetPipeline());

			vkCmdDraw(offlineCommandBuffer, 3, 1, 0, 0);

			vkCmdEndRenderPass(offlineCommandBuffer);


			mCommandBuffer->FlushCommandBuffer(offlineCommandBuffer);

			vkQueueWaitIdle(GVulkanRHI->GetQueue());

			mCommandBuffer.SafeRelease();
			mDescriptor.SafeRelease();
			mPipeline.SafeRelease();
			mRenderPass.SafeRelease();
			mFrameBuffer.SafeRelease();
		});
}

void BrbflutProcess::OnResize()
{

}
